﻿using AELTAPLC;
using IDevSerialBasic;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using RestSharp;
using System.Net.Sockets;
using System.Net;
using Futil;
using SuperWebSocket;
using SuperSocket.SocketBase.Config;
using WebSocket4Net;
using WebSocket = WebSocket4Net.WebSocket;
using System.Xml;

namespace OKDebug
{
    public partial class Form1 : Form
    {
        public PLC_S7200.PLC_S7200 _plc_s7200 = new PLC_S7200.PLC_S7200();
        public SanLingPLC.SanLingPLC _plc_sanling = new SanLingPLC.SanLingPLC();
        public DevPLC_AELTA _AeltaPLC = new DevPLC_AELTA();
        public IPort.ILogicPort _port = null;
        public IDevSerialBasic.IDevSerial _dev = null;
        public PortUdpClient.PortUdpClient _portUdpClient = null;
        public PortTcpClient.PortTcpClient _portTcpClient = null;
        WebSocketServer _WebSocketServer = new WebSocketServer();
        WebSocketSession _CurrentWebSocketSession = null;
        public static WebSocket webSocket4Net = null;
        FrmModbus _FrmModbus = new FrmModbus();
        public Form1()
        {
            InitializeComponent();
        }

        private delegate void AppendTextToSerialContextHandler(string code);
        private delegate void ShowNJHandler(string val);
        private delegate void ShowHJHandler(string val);
        private delegate void SwitchBtnTxtHandler(int btncode);
        private delegate void OpenBTNUIHandler();
        private delegate void MNPLCDataSaveHandler();

        public void SwitchBtnTxt(int btncode)
        {
            if (this.InvokeRequired)
            {
                SwitchBtnTxtHandler s = new SwitchBtnTxtHandler(SwitchBtnTxt);
                this.BeginInvoke(s, new object[] { btncode });
            }
            else
            {
                switch (btncode)
                {
                    case 1:
                        this.btnStartTCPServer.Text = "已开启TCP";
                        btnStartTCPServer.ForeColor = Color.White;
                        this.btnStartTCPServer.BackColor = Color.Green;
                        break;
                    case 2:
                        this.btnStartUDPServer.Text = "已开启UDP";
                        btnStartUDPServer.ForeColor = Color.White;
                        this.btnStartUDPServer.BackColor = Color.Green;
                        break;
                }
            }
        }

        public void AppendTextToSerialContext(string text)
        {
            if (this.InvokeRequired)
            {
                AppendTextToSerialContextHandler s = new AppendTextToSerialContextHandler(AppendTextToSerialContext);
                this.BeginInvoke(s, new object[] { text });
            }
            else
            {
                this.txtSerialContext.AppendText(text);
            }
        }

        /// <summary>
        /// 模拟PLC数据保存
        /// </summary>
        public void MNPLCDataSave()
        {
            if (this.InvokeRequired)
            {
                MNPLCDataSaveHandler s = new MNPLCDataSaveHandler(MNPLCDataSave);
                this.BeginInvoke(s, new object[] {  });
            }
            else
            {
                _frmPLCMN.DisplayData();
                _frmPLCMN.SaveData();
            }
        }

        public void OpenBTNUI()
        {
            if (this.InvokeRequired)
            {
                OpenBTNUIHandler s = new OpenBTNUIHandler(OpenBTNUI);
                this.BeginInvoke(s, new object[] {  });
            }
            else
            {
                this.btnTCPOpen.Text = "已连接";
                btnTCPOpen.ForeColor = Color.White;
                this.btnTCPOpen.BackColor = Color.Green;
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if ("已开启".Equals(this.btnOpen.Text.Trim()))
            {
                if (MessageBox.Show("是否关闭？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    _portUdpClient.Close(string.Empty);
                    this.btnOpen.Text = "开启";
                    btnOpen.ForeColor = SystemColors.ControlText;
                    btnOpen.BackColor = SystemColors.Control;
                };

                return;
            }

            string cfg = "";
            if (string.IsNullOrEmpty(this.txtUdpServerIP.Text.Trim()))
            {
                MessageBox.Show("UdpServerIP空！");
                return;
            }

            if (string.IsNullOrEmpty(this.txtUdpServerPort.Text.Trim()))
            {
                MessageBox.Show("UdpServerPort空！");
                return;
            }

            if (string.IsNullOrEmpty(this.txtUdpLocalIP.Text.Trim()))
            {
                MessageBox.Show("UdpLocalIP空！");
                return;
            }

            if (string.IsNullOrEmpty(this.txtUdpServerPort.Text.Trim()))
            {
                MessageBox.Show("UdpServerPort空！");
                return;
            }
            _portUdpClient = new PortUdpClient.PortUdpClient();
            _portUdpClient.OnPortData += new IPort.OnPortDataHandler(udp_OnPortData);
            cfg = this.txtUdpServerIP.Text.Trim() + ":" + this.txtUdpServerPort.Text.Trim() + ";" + this.txtUdpLocalIP.Text.Trim() + ":" + this.txtUdpLocalPort.Text.Trim()+ ",,,,,";
            bool result=_portUdpClient.Open(cfg);
            if (result)
            {
                this.btnOpen.Text = "已开启";
                btnOpen.ForeColor = Color.White;
                this.btnOpen.BackColor = Color.Green;
            }
            else
            {
                _portUdpClient = null;
            }
        }

        public void udp_OnPortData(string portname, byte[] dtaBuffer)
        {
            if (portname == "CONN-ERR")
            {
                //this.btnTCPOpen.Text = "Open";
                MessageBox.Show("连接失败！");
                return;
            }
            else if(portname == "CONN-OK")
            {
                OpenBTNUI();
                return;
            }

            string msg = Encoding.UTF8.GetString(dtaBuffer).Trim();
            if (this.cbxUtf.Checked)
            {
                msg = portname + " " + Encoding.UTF8.GetString(dtaBuffer).Trim();
            }
            else
            {
                msg = portname + " " + BitConverter.ToString(dtaBuffer);
            }
            
            this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+" "+msg+"\r\n");
        }

        private void btnOpenCom_Click(object sender, EventArgs e)
        {
            if ("已开启".Equals(this.btnOpenCom.Text.Trim()))
            {
                if (MessageBox.Show("是否断开？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    this.btnOpenCom.Text = "开启";
                    btnOpenCom.ForeColor = SystemColors.ControlText;
                    btnOpenCom.BackColor = SystemColors.Control;
                    _port.Close(string.Empty);
                };

                return;
            }

            this._port = IOHelper.ObjCreator<IPort.ILogicPort>.Instance.CreateLogicDevice("ILogicPort", ".\\PortSerial.dll");
            string strPort = this.txtPort.Text.Trim();
            if (string.IsNullOrEmpty(strPort))
            {
                MessageBox.Show("端口不能为空！");
                this.txtPort.Focus();
                return;
            }

            string baud = txtbaud.Text.Trim();
            string databit = txtdatabit.Text.Trim();
            string stopbit = txtstopbit.Text.Trim();
            string checkbit = txtcheckbit.Text.Trim();

            int _baud = 0;
            int _databit = 0;
            int _stopbit = 0;
            int _checkbit = 0;
            if (string.IsNullOrEmpty(baud))
            {
                MessageBox.Show("波特率空！");
                return;
            }
            else
            {
                try
                {
                    _baud = Convert.ToInt32(baud);
                }
                catch
                {
                    MessageBox.Show("波特率格式不对！");
                    return;
                }
            }

            if (string.IsNullOrEmpty(databit))
            {
                MessageBox.Show("数据位空！");
                return;
            }
            else
            {
                try
                {
                    _databit = Convert.ToInt32(databit);
                }
                catch
                {
                    MessageBox.Show("数据位格式不对！");
                    return;
                }
            }

            if (string.IsNullOrEmpty(stopbit))
            {
                MessageBox.Show("停止位空！");
                return;
            }
            else
            {
                try
                {
                    _stopbit = Convert.ToInt32(stopbit);
                }
                catch
                {
                    MessageBox.Show("停止位格式不对！");
                    return;
                }
            }

            if (string.IsNullOrEmpty(checkbit))
            {
                MessageBox.Show("校验位空！");
                return;
            }
            else
            {
                try
                {
                    _checkbit = Convert.ToInt32(checkbit);
                }
                catch
                {
                    MessageBox.Show("校验位格式不对！");
                    return;
                }
            }

            try
            {
                string cfg = strPort + ","+baud+","+databit+","+checkbit+","+stopbit+",.\\PortSerial.dll";
                if (this._port.Open(cfg))
                {
                    IPort.PortManager.AddPort(strPort, this._port);
                    _dev = IOHelper.ObjCreator<IDevSerialBasic.IDevSerial>.Instance.CreateLogicDevice("IDevSerial", ".\\DevSerialBasic.dll");
                    _dev.DevName = strPort;
                    _dev.PortName = strPort;
                    _dev.Open();
                    IOHelper.DebugMsg.Log("_dev.PortName------" + _dev.PortName);
                    _dev.OnDevData += new OnDevDataHandler(SerialPort_OnDevData);
                    btnOpenCom.Text = "已开启";
                    btnOpenCom.ForeColor = Color.White;
                    btnOpenCom.BackColor = Color.Green;
                    _PortType = 1;
                }
            }
            catch(Exception ex)
            {
                btnOpenCom.Text = "串口开启失败";
                btnOpenCom.BackColor = Color.Red;
            }
        }

        public void SerialPort_OnDevData(string portName, byte[] bytes)
        {
            if (bytes == null) return;
            string str = string.Empty;
            str = BitConverter.ToString(bytes);
            if (cbxUtf.Checked)
            {
                str = Encoding.UTF8.GetString(bytes).Trim();
            }

            this.AppendTextToSerialContext(str + "\r\n");
        }

        public int _SendCount = 0;
        private void btnSend_Click(object sender, EventArgs e)
        {
            if (_dev == null)
            {
                MessageBox.Show("未打开串口！");
                return;
            }

            string val = this.txtVal.Text.Trim();
            if (string.IsNullOrEmpty(val))
            {
                MessageBox.Show("待发送代码不能为空！");
                this.txtVal.Focus();
                return;
            }

            List<byte> list = ConvertToByteList(val);
            IOHelper.DebugMsg.Log("向PLC发送:" + list.ToArray());
            _dev.SetData(list.ToArray());
            _SendCount++;
            btnSend.Text = "发送"+_SendCount;
            MessageBox.Show("已发送！");
        }

        public List<byte> ConvertToByteList(string val)
        {
            List<byte> list = new List<byte> { };
            string[] arr = val.Split('-');
            if (arr.Length > 0)
            {
                List<string> strlist = arr.ToList();
                foreach (var str in strlist)
                {
                    list.Add(Convert.ToByte("0x" + str, 16));
                }
            }

            return list;
        }

        FrmPLCMN _frmPLCMN = new FrmPLCMN();
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            _frmPLCMN._pLCMN = _plcMN;
            _frmPLCMN._pLCMN.PLCAddrValList = new List<PLCAddrVal>();
            string plc_mn_name = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_name", "value");
            string plc_mn_address = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_address", "value");
            string plc_mn_length = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_length", "value");
            string plc_mn_type = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_type", "value");
            string plc_mn_value = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_value", "value");
            string plc_mn_bigmode = XmlHelper.GetNodeAttribute(System.Windows.Forms.Application.ExecutablePath + ".config", "configuration/appSettings/add", "key", "plc_mn_bigmode", "value");
            _frmPLCMN._pLCMN.BIGMODE = "TRUE".Equals(plc_mn_bigmode) ? true : false;
            string[] plc_mn_name_arr = plc_mn_name.Split(',');
            string[] plc_mn_address_arr = plc_mn_address.Split(',');
            string[] plc_mn_length_arr = plc_mn_length.Split(',');
            string[] plc_mn_type_arr = plc_mn_type.Split(',');
            string[] plc_mn_value_arr = plc_mn_value.Split(',');
            for(var i=0;i< plc_mn_address_arr.Length; i++)
            {
                PLCAddrVal pLCAddrVal = new PLCAddrVal();
                if (plc_mn_name_arr.Length > i)
                {
                    pLCAddrVal.Name = plc_mn_name_arr[i];
                }
                
                pLCAddrVal.Addr = plc_mn_address_arr[i];

                if (plc_mn_length_arr.Length > i)
                {
                    pLCAddrVal.Length = plc_mn_length_arr[i];
                }
                
                if (plc_mn_type_arr.Length > 1)
                {
                    pLCAddrVal.Type = plc_mn_type_arr[i];
                }
                
                if (plc_mn_value_arr.Length > i)
                {
                    pLCAddrVal.Val = plc_mn_value_arr[i];
                }
                
                _frmPLCMN._pLCMN.PLCAddrValList.Add(pLCAddrVal);
            }
        }

        private void btnTCPOpen_Click(object sender, EventArgs e)
        {
            if ("已连接".Equals(this.btnTCPOpen.Text.Trim()))
            {
                if (MessageBox.Show("是否断开？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    _portTcpClient.Close(string.Empty);
                    this.btnTCPOpen.Text = "连接";
                    btnTCPOpen.ForeColor = SystemColors.ControlText;
                    btnTCPOpen.BackColor = SystemColors.Control;
                };

                return;
            }

            string cfg = "";
            if (string.IsNullOrEmpty(this.txtTCPRemoteIP.Text.Trim()))
            {
                MessageBox.Show("TCPServerIP空！");
                return;
            }

            if (string.IsNullOrEmpty(this.txtTCPRemotePort.Text.Trim()))
            {
                MessageBox.Show("TCPServerPort空！");
                return;
            }
            _portTcpClient = new PortTcpClient.PortTcpClient();
            _portTcpClient.OnPortData += new IPort.OnPortDataHandler(udp_OnPortData);
            cfg = this.txtTCPRemoteIP.Text.Trim() + ":" + this.txtTCPRemotePort.Text.Trim() + ",,,,,";
            bool result = _portTcpClient.Open(cfg);
            if (result)
            {
                //this.btnTCPOpen.Text = "连接中...";
                //this.btnTCPOpen.BackColor = Color.Green;
            }
            else
            {
                MessageBox.Show("连接失败！");
                _portTcpClient = null;
            }
        }

        public List<Key> _HeaderList = new List<Key>();
        private void btnPost_Click(object sender, EventArgs e)
        {
            try
            {
                string url = this.txtWebApiAddr.Text.Trim();
                if (string.IsNullOrEmpty(url))
                {
                    MessageBox.Show("webapi地址空。");
                    return;
                }


                //var client = new RestClient(url);
                //client.Timeout = -1;
                //var request = new RestRequest(Method.POST);
                //request.AddHeader("Content-Type", "application/json");
                //foreach(var header in _HeaderList)
                //{
                //    request.AddHeader(header.Name, header.Code);
                //}
                //string json = this.txtWebapiIN.Text.Trim();
                //request.AddParameter("application/json", json, ParameterType.RequestBody);
                //IRestResponse response = client.Execute(request);
                //string res = response.Content;
                //this.txtSerialContext.Text = res;
                //IOHelper.DebugMsg.Log("UpToMES : " + res);

                string reqjson = this.txtWebapiIN.Text.Trim();
                string rspjson = HttpHelper.PostToURL(url, reqjson);
                this.txtSerialContext.Text = rspjson;
            }
            catch (Exception ex)
            {
                this.txtSerialContext.Text = "UpToMES Error :" + ex.Message + ex.StackTrace;
                IOHelper.DebugMsg.Log("UpToMES Error :" + ex.Message + ex.StackTrace);
            }
        }

        private void lblJsonEX_Click(object sender, EventArgs e)
        {
            FrmPostEx frmPostEx = new FrmPostEx();
            frmPostEx._ParamJSON = this.txtWebapiIN.Text.Trim();
            frmPostEx.ShowDialog();
            if(frmPostEx.DialogResult== DialogResult.OK)
            {
                this.txtWebapiIN.Text = frmPostEx._ParamJSON;
                _HeaderList = frmPostEx._HeaderList;
            }
        }

        int _PortType = 1;

        public void SendTcpData(string val)
        {
            if (_TcpSocConnection == null)
            {
                MessageBox.Show("无客户端连接！");
                return;
            }

            try
            {
                List<byte> list = ConvertToByteList(val);
                _TcpSocConnection.Send(list.ToArray());
                MessageBox.Show("已发送！");
            }
            catch(Exception ex)
            {
                MessageBox.Show("发送异常："+ex.ToString());
            }
        }

        Socket _TcpSocketWatch;
        Socket _TcpSocConnection = null;
        Thread _TcpThreadWatch;

        Socket _UdpSocketWatch;

        private void btnStartUDPServer_Click(object sender, EventArgs e)
        {
            if ("已开启UDP".Equals(this.btnStartUDPServer.Text.Trim()))
            {
                if (MessageBox.Show("是否关闭UDP服务？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    this.btnStartUDPServer.Text = "开启UDP";
                    btnStartUDPServer.ForeColor = SystemColors.ControlText;
                    btnStartUDPServer.BackColor = SystemColors.Control;
                };

                return;
            }

            string port = this.txtServerPort.Text.Trim();
            if (string.IsNullOrEmpty(port))
            {
                MessageBox.Show("端口号空！");
                this.txtServerPort.Focus();
                return;
            }

            string ip = this.txtServerIP.Text.Trim();
            if (string.IsNullOrEmpty(ip))
            {
                MessageBox.Show("IP空！");
                this.txtServerIP.Focus();
                return;
            }

            try
            {
                int _port = Convert.ToInt32(port);
                _UdpSocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                _UdpSocketWatch.Bind(new IPEndPoint(IPAddress.Parse(ip), _port));
                new Thread(UDPWatchConnecting)
                {
                    IsBackground = true
                }.Start();
                this.SwitchBtnTxt(2);
                _PortType = 3;
            }
            catch(Exception ex)
            {
                MessageBox.Show("打开异常:" + ex.ToString());
            }
        }

        private void UDPWatchConnecting()
        {
            while (true)
            {
                byte[] recdata = new byte[1024];
                EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
                int count = _UdpSocketWatch.ReceiveFrom(recdata, ref endPoint);
                if (count > 0)
                {
                    byte[] _recdata = new byte[count];
                    Array.Copy(recdata, 0, _recdata, 0, count);
                    string message = Encoding.UTF8.GetString(_recdata, 0, count);
                    this.AppendTextToSerialContext(message + "\r\n");
                }
            }
        }

        private void btnStartTCPServer_Click(object sender, EventArgs e)
        {
            if ("已开启TCP".Equals(this.btnStartTCPServer.Text.Trim()))
            {
                if (MessageBox.Show("是否关闭TCP服务？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    try
                    {
                        _TcpSocketWatch.Close();
                        _TcpSocketWatch.Dispose();

                        _TcpSocConnection.Close();
                        _TcpSocConnection.Dispose();
                    }
                    catch
                    {

                    }

                    this.btnStartTCPServer.Text = "开启TCP";
                    btnStartTCPServer.ForeColor = SystemColors.ControlText;
                    btnStartTCPServer.BackColor = SystemColors.Control;
                };

                return;
            }

            string port = this.txtServerPort.Text.Trim();
            if (string.IsNullOrEmpty(port))
            {
                MessageBox.Show("端口号空！");
                this.txtServerPort.Focus();
                return;
            }

            string ip = this.txtServerIP.Text.Trim();
            if (string.IsNullOrEmpty(ip))
            {
                MessageBox.Show("IP空！");
                this.txtServerIP.Focus();
                return;
            }

            int _port = Convert.ToInt32(port);

            try
            {
                _TcpSocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ipaddress = IPAddress.Parse(ip);
                IPEndPoint endpoint = new IPEndPoint(ipaddress, _port);
                _TcpSocketWatch.Bind(endpoint);
                _TcpSocketWatch.Listen(20);
                _TcpThreadWatch = new Thread(TCPWatchConnecting);
                _TcpThreadWatch.IsBackground = true;
                _TcpThreadWatch.Start();
                this.SwitchBtnTxt(1);
                _PortType = 2;
            }
            catch(Exception ex)
            {
                MessageBox.Show("打开异常:"+ex.ToString());
            }
        }

        private void TCPWatchConnecting()
        {
            while (true)
            {
                try
                {
                    _TcpSocConnection = _TcpSocketWatch.Accept();
                }
                catch
                {
                    return;
                }
                
                this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 客户端【" + _TcpSocConnection.RemoteEndPoint + "】接入...\r\n");
                ParameterizedThreadStart pts = new ParameterizedThreadStart(TCPServerRecMsg);
                Thread thr = new Thread(pts);
                thr.IsBackground = true;
                thr.Start(_TcpSocConnection);
            }
        }

        private CancellationTokenSource cts = new CancellationTokenSource();

        /// <summary>
        /// 接收客户端消息线程
        /// </summary>
        /// <param name="socketClientObj"></param>
        private void TCPServerRecMsg(object socketClientObj)
        {
            Socket socketClient = (Socket)socketClientObj;
            while (!cts.IsCancellationRequested)
            {
                byte[] arrServerRecMsg = new byte[1024 * 1024];
                int length = 0;
                try
                {
                    length = socketClient.Receive(arrServerRecMsg);
                }
                catch
                {
                    this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 连接断开...\r\n");
                    return;
                }

                lock (_plcMN.PLCAddrValList)
                {
                    if (length != 0)
                    {
                        string strSRecMsg = string.Empty;
                        string _strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
                        if (this.cbxUtf.Checked)
                        {
                            strSRecMsg = _strSRecMsg;
                        }
                        else
                        {
                            strSRecMsg = BitConverter.ToString(arrServerRecMsg, 0, length);
                        }

                        lock (_frmPLCMN._pLCMN.PLCAddrValList)
                        {
                            //模拟PLC读取
                            if (_strSRecMsg.ToLower().Contains("plc_read"))
                            {
                                string[] arr = _strSRecMsg.Split('#');
                                if (arr.Length > 1)
                                {
                                    string plc_mn_addr = arr[1];
                                    PLCAddrVal pLCAddrVal = _plcMN.PLCAddrValList.FirstOrDefault(p => p.Addr.Equals(plc_mn_addr));
                                    if (pLCAddrVal != null)
                                    {
                                        _strSRecMsg += "#" + pLCAddrVal.Val;
                                        _strSRecMsg = "OK#" + _strSRecMsg;
                                    }
                                    else
                                    {
                                        _strSRecMsg += "#未找到点位";
                                        _strSRecMsg = "NO#" + _strSRecMsg;
                                    }

                                    byte[] buffer = Encoding.UTF8.GetBytes(_strSRecMsg);
                                    socketClient.Send(buffer);
                                    this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + _strSRecMsg + "\r\n");
                                }
                            }
                            else if (_strSRecMsg.ToLower().Contains("plc_write")) //模拟PLC写入
                            {
                                string[] arr = _strSRecMsg.Split('#');
                                if (arr.Length > 2)
                                {
                                    string plc_mn_addr = arr[1];
                                    PLCAddrVal pLCAddrVal = _plcMN.PLCAddrValList.FirstOrDefault(p => p.Addr.Equals(plc_mn_addr));
                                    if (pLCAddrVal != null)
                                    {
                                        pLCAddrVal.Val = arr[2];
                                        _strSRecMsg = "OK#" + _strSRecMsg;
                                        MNPLCDataSave();
                                    }
                                    else
                                    {
                                        _strSRecMsg = "NO#" + _strSRecMsg + "未找到点位";
                                    }
                                }

                                byte[] buffer = Encoding.UTF8.GetBytes(_strSRecMsg);
                                socketClient.Send(buffer);
                                this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + _strSRecMsg + "\r\n");
                            }
                            else if (_strSRecMsg.ToLower().Contains("plc_batch_write")) //模拟PLC批量写入
                            {
                                string[] arr = _strSRecMsg.Split('#');
                                if (arr.Length > 2)
                                {
                                    //212   208
                                    string plc_mn_addr = arr[1];
                                    string[] tempArr = arr[2].Split('-');
                                    byte[] valBytes = new byte[tempArr.Length];
                                    for (int i = 0; i < tempArr.Length; i++)
                                    {
                                        valBytes[i] = Convert.ToByte(tempArr[i], 16);
                                    }

                                    bool isStart = false;
                                    bool writeFlag = false;
                                    int readIndex = 0;

                                    try
                                    {
                                        foreach (var plcAddrVal in _frmPLCMN._pLCMN.PLCAddrValList)
                                        {
                                            if (plcAddrVal.Addr.Equals(plc_mn_addr))
                                            {
                                                isStart = true;
                                            }

                                            int _length = 0;
                                            if (isStart)
                                            {
                                                try
                                                {
                                                    if ("0.5".Equals(plcAddrVal.Length))
                                                    {
                                                        _length = 1;
                                                    }
                                                    else
                                                    {
                                                        _length = Convert.ToInt32(plcAddrVal.Length);
                                                        _length = _length * 2;
                                                    }
                                                }
                                                catch
                                                {

                                                }

                                                object valObj = "";
                                                switch (plcAddrVal.Type)
                                                {
                                                    case "ascii":
                                                        valObj = Encoding.UTF8.GetString(valBytes, readIndex, _length);
                                                        valObj = valObj.ToString().Replace("\0",string.Empty);
                                                        break;
                                                    case "unicode":
                                                        valObj = Encoding.Unicode.GetString(valBytes, readIndex, _length);
                                                        valObj = valObj.ToString().Replace("\0", string.Empty);
                                                        break;
                                                    case "short":

                                                        if (_plcMN.BIGMODE)
                                                        {
                                                            byte[] _buf = new byte[2];
                                                            _buf[0] = valBytes[readIndex + 1];
                                                            _buf[1] = valBytes[readIndex];
                                                            valObj = BitConverter.ToUInt16(_buf, 0);
                                                        }
                                                        else
                                                        {
                                                            valObj = BitConverter.ToUInt16(valBytes, readIndex);
                                                        }
                                                        
                                                        break;
                                                    case "float":

                                                        if (_plcMN.BIGMODE)
                                                        {
                                                            byte[] _buf = new byte[4];
                                                            _buf[0] = valBytes[readIndex + 3];
                                                            _buf[1] = valBytes[readIndex + 2];
                                                            _buf[2] = valBytes[readIndex + 1];
                                                            _buf[3] = valBytes[readIndex];
                                                            valObj = BitConverter.ToSingle(_buf, 0);
                                                        }
                                                        else
                                                        {
                                                            valObj = BitConverter.ToSingle(valBytes, readIndex);
                                                        }
                                                        
                                                        break;
                                                    case "int":
                                                        if (_plcMN.BIGMODE)
                                                        {
                                                            byte[] _buf = new byte[4];
                                                            _buf[0] = valBytes[readIndex + 3];
                                                            _buf[1] = valBytes[readIndex + 2];
                                                            _buf[2] = valBytes[readIndex + 1];
                                                            _buf[3] = valBytes[readIndex];
                                                            valObj = BitConverter.ToInt32(_buf, 0);
                                                        }
                                                        else
                                                        {
                                                            valObj = BitConverter.ToInt32(valBytes, readIndex);
                                                        }

                                                        break;
                                                    case "byte":
                                                        valObj = valBytes[readIndex];
                                                        break;
                                                }

                                                plcAddrVal.Val = valObj.ToString();
                                                readIndex += _length;
                                                if (readIndex >= valBytes.Length)
                                                {
                                                    break;
                                                }
                                            }
                                        }

                                        if (isStart)
                                        {
                                            writeFlag = true;
                                        }
                                        else
                                        {
                                            _strSRecMsg += "未找到点位";
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        writeFlag = false;
                                        _strSRecMsg +=" 字节数组长度="+ valBytes.Length + " readIndex=" + readIndex+" "+ex.ToString() + ex.StackTrace;
                                    }

                                    if (writeFlag)
                                    {
                                        _strSRecMsg = "OK#" + _strSRecMsg;
                                        MNPLCDataSave();
                                    }
                                    else
                                    {
                                        _strSRecMsg = "NO#" + _strSRecMsg;
                                    }
                                }

                                byte[] buffer = Encoding.UTF8.GetBytes(_strSRecMsg);
                                socketClient.Send(buffer);
                                this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + _strSRecMsg + "\r\n");
                            }
                            else
                            {
                                this.AppendTextToSerialContext(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + strSRecMsg + "\r\n");
                            }
                        }
                    }
                }
            }
        }

        private void btnBuildBiz_Click(object sender, EventArgs e)
        {
            
        }

        private void btnPLCMN_Click(object sender, EventArgs e)
        {
            FrmPLCMN frmPLCMN = new FrmPLCMN();
            frmPLCMN.ShowDialog();
        }

        /// <summary>
        /// 获取指定字符的个数
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="sign">指定字符</param>
        /// <returns>个数</returns>
        private int GetStrCount(string str, string sign)
        {
            if (!string.IsNullOrEmpty(str) && !string.IsNullOrEmpty(sign) && str.Contains(sign))
            {
                string newStr = str.Replace(sign, "");
                return (str.Length - newStr.Length) / sign.Length;
            }
            return 0;
        }

        private void btnSendTCP_Click(object sender, EventArgs e)
        {
            if (_portTcpClient == null)
            {
                MessageBox.Show("请先打开tcp端口！");
                return;
            }

            byte[] buffer;

            string val = this.txtVal.Text.Trim();
            if (string.IsNullOrEmpty(val))
            {
                MessageBox.Show("发送内容不能为空！");
                this.txtVal.Focus();
                return;
            }

            List<byte> list = new List<byte> { };
            string[] arr = val.Split('-');
            if (arr.Length > 1)
            {
                try
                {
                    List<string> strlist = arr.ToList();
                    foreach (var str in strlist)
                    {
                        list.Add(Convert.ToByte("0x" + str, 16));
                    }

                    buffer = list.ToArray();
                }
                catch
                {
                    buffer = Encoding.UTF8.GetBytes(val);
                }
            }
            else
            {
                buffer = Encoding.UTF8.GetBytes(val);
            }

            bool result = _portTcpClient.WriteData(buffer);
            if (result)
            {
                MessageBox.Show("发送成功！");
            }
            else
            {
                MessageBox.Show("发送失败！");
            }
        }

        private void BtnTcpServerSend_Click(object sender, EventArgs e)
        {
            if (_TcpSocConnection == null)
            {
                MessageBox.Show("请开启TCP Server！");
                return;
            }

            string val = this.txtVal.Text.Trim().Replace(" ","-");
            if (string.IsNullOrEmpty(val))
            {
                val = "00 00";
            }

            byte[] buffer= ConvertToByteList(val).ToArray();
            _TcpSocConnection.Send(buffer);
            MessageBox.Show("发送成功！");
        }

        private void BtnUdpServerSend_Click(object sender, EventArgs e)
        {

        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            this.txtSerialContext.Text = string.Empty;
        }

        private void btnOtherPLC_Click(object sender, EventArgs e)
        {
            FrmOtherPLC frmOtherPLC = new FrmOtherPLC();
            frmOtherPLC.Show();
        }

        private void btnSanLingPLC_Click(object sender, EventArgs e)
        {
            FrmSanLingPLC frmSanLingPLC = new FrmSanLingPLC();
            frmSanLingPLC.Show();
        }

        private void btnXiMenZiPLC_Click(object sender, EventArgs e)
        {
            FrmXiMenZiPLC frmXiMenZiPLC = new FrmXiMenZiPLC();
            frmXiMenZiPLC.Show();
        }

        private void btnStartWss_Click(object sender, EventArgs e)
        {
            if ("已开启".Equals(this.btnStartWss.Text.Trim()))
            {
                if (MessageBox.Show("是否关闭？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    _WebSocketServer.Stop();
                    _WebSocketServer.Dispose();
                    _WebSocketServer = new WebSocketServer();
                    this.btnStartWss.Text = "开启";
                    btnStartWss.ForeColor = SystemColors.ControlText;
                    btnStartWss.BackColor = SystemColors.Control;
                };

                return;
            }

            this.StartWebsocketServer();
        }

        private void StartWebsocketServer()
        {
            if (string.IsNullOrEmpty(this.txtWebsocketPort.Text.Trim()))
            {
                MessageBox.Show("端口号不能为空！");
                return;
            }

            int port = Convert.ToInt32(this.txtWebsocketPort.Text.Trim());
            //if(_WebSocketServer.State)
            _WebSocketServer.NewSessionConnected += WebSocketServer_NewSessionConnected;
            _WebSocketServer.NewMessageReceived += WebSocketServer_NewMessageReceived;
            _WebSocketServer.SessionClosed += WebSocketServer_SessionClosed;
            ServerConfig serverConfig = new ServerConfig();
            serverConfig.Ip = "127.0.0.1";
            serverConfig.Port = port;
            //serverConfig.ReceiveBufferSize = 10240;
            if (!_WebSocketServer.Setup(serverConfig))
            {
                MessageBox.Show("设置服务监听失败！");
                return;
            }

            if (!_WebSocketServer.Start())
            {
                MessageBox.Show("启动服务监听失败！");
                return;
            }

            this.btnStartWss.Text = "已开启";
            this.btnStartWss.ForeColor = Color.White;
            this.btnStartWss.BackColor = Color.Green;
        }

        private void WebSocketServer_NewSessionConnected(WebSocketSession session)
        {
            _CurrentWebSocketSession = session;
            this.txtSerialContext.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+" 客户端【"+ session.SocketSession.RemoteEndPoint.ToString() + "】接入..." + "\r\n");
        }

        private void WebSocketServer_NewMessageReceived(WebSocketSession session, string value)
        {
            this.txtSerialContext.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 收到客户端【"+ session.SocketSession.RemoteEndPoint.ToString() + "】数据\r\n" + value + "\r\n");
        }

        private void WebSocketServer_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
        {
            _CurrentWebSocketSession = null;
            this.txtSerialContext.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "客户端【" + session.SocketSession.RemoteEndPoint.ToString() + "】关闭，原因：" + value + "\r\n");
        }

        private void btnSendWSJson_Click(object sender, EventArgs e)
        {
            string content = this.txtVal.Text.Trim();
            if (_CurrentWebSocketSession == null)
            {
                MessageBox.Show("没有客户端连接！");
            }
            else
            {
                if (string.IsNullOrEmpty(content))
                {
                    MessageBox.Show("内容空！");
                    return;
                }

                _CurrentWebSocketSession.Send(content);
                MessageBox.Show("已发送！");
            }
        }

        private void btnConnectWebsocket_Click(object sender, EventArgs e)
        {
            if (btnConnectWebsocket.Text.Equals("已连接"))
            {
                if (MessageBox.Show("是否断开连接？", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
                {
                    try
                    {
                        webSocket4Net.Close();
                    }
                    catch
                    {

                    }
                    
                    btnConnectWebsocket.ForeColor = SystemColors.ControlText;
                    btnConnectWebsocket.BackColor = SystemColors.Control;
                    btnConnectWebsocket.Text = "连接";
                };

                return;
            }

            string ip = this.txtWebsocketIP.Text.Trim();
            string port = this.txtWebsocketPort.Text.Trim();
            string path = this.txtWebsocketPath.Text.Trim();

            webSocket4Net = new WebSocket("ws://" + ip + ":" + port + "/" + path);
            webSocket4Net.Opened += WebSocket4Net_Opened;
            webSocket4Net.Closed += WebSocket4Net_Closed;
            webSocket4Net.MessageReceived += WebSocket4Net_MessageReceived;
            webSocket4Net.Open();
        }

        private void WebSocket4Net_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            this.txtSerialContext.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 收到服务端数据\r\n" + e.Message + "\r\n");
        }

        private void WebSocket4Net_Opened(object sender, EventArgs e)
        {
            btnConnectWebsocket.ForeColor = Color.White;
            btnConnectWebsocket.BackColor = Color.Green;
            btnConnectWebsocket.Text = "已连接";
        }

        private void WebSocket4Net_Closed(object sender, EventArgs e)
        {
            this.txtSerialContext.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " websocket连接断开\r\n");
            btnConnectWebsocket.ForeColor = SystemColors.ControlText;
            btnConnectWebsocket.BackColor = SystemColors.Control;
            btnConnectWebsocket.Text = "连接";
        }

        private void btnSendWSJson2_Click(object sender, EventArgs e)
        {
            if (webSocket4Net == null)
            {
                MessageBox.Show("未连接！");
                return;
            }

            webSocket4Net.Send(this.txtVal.Text.Trim());
            MessageBox.Show("已发送！");
        }

        private void btnModbus_Click(object sender, EventArgs e)
        {
            DialogResult dialogResult = _FrmModbus.ShowDialog();
            if(dialogResult== DialogResult.OK)
            {
                this.txtVal.Text = _FrmModbus.MESSAGE;
                this.txtVal.Focus();
            }
        }

        private void btnOPC_Click(object sender, EventArgs e)
        {
            FrmOPC frmOPC = new FrmOPC();
            frmOPC.ShowDialog();
        }
        
        PLCMN _plcMN = new PLCMN();
        private void btnMNPLC_Click(object sender, EventArgs e)
        {
            _frmPLCMN.ShowDialog();
        }

        private void btnOpenMsgDir_Click(object sender, EventArgs e)
        {
            string path = Environment.CurrentDirectory+"\\msg";
            if (!Directory.Exists(path))
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(path);
                // 创建目录
                directoryInfo.Create();
            }

            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.InitialDirectory = path;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "txt files (*.txt)|*.txt";
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string file = fileDialog.FileName;

                try
                {
                    string fileContent = File.ReadAllText(file);
                    txtVal.Text = fileContent;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error reading file: " + ex.Message);
                }
            }
        }

        private void btnOpenAbout_Click(object sender, EventArgs e)
        {
            FrmAbout frmAbout = new FrmAbout();
            frmAbout.ShowDialog();
        }

        private void btnSendUDP_Click(object sender, EventArgs e)
        {
            if (_portUdpClient == null)
            {
                MessageBox.Show("请先打开udp端口！");
                this.txtUdpLocalPort.Focus();
                return;
            }

            string val = this.txtVal.Text.Trim();
            if (string.IsNullOrEmpty(val))
            {
                MessageBox.Show("发送udp内容不能为空！");
                this.txtVal.Focus();
                return;
            }

            byte[] buffer;
            List<byte> list = new List<byte> { };
            string[] arr = val.Split('-');
            if (arr.Length > 1)
            {
                List<string> strlist = arr.ToList();
                foreach (var str in strlist)
                {
                    list.Add(Convert.ToByte("0x" + str, 16));
                }

                buffer = list.ToArray();
            }
            else
            {
                buffer = Encoding.UTF8.GetBytes(val + "\r\n");
            }

            bool result=_portUdpClient.WriteData(buffer);
            if (result)
            {
                MessageBox.Show("发送成功！");
            }
            else
            {
                MessageBox.Show("发送失败！");
            }
        }

        private void btnLoadWebservice_Click(object sender, EventArgs e)
        {
            FrmWebservice frmWebservice = new FrmWebservice();
            frmWebservice.ShowDialog();
        }
    }
}
